#include "ULGfx_Bomb.h"
#include <iostream>
#include <SDL/sprig.h>

//#define ULG_BOMB_DEBUG

#define DEFAULT_FRAME_INTERVAL	90	

#define BOMB_BOMB_STAT_NORMAL_IMAGE_Y	0
#define BOMB_BOMB_STAT_SCARED_IMAGE_Y	67
#define BOMB_BOMB_STAT_EXPLODED_IMAGE_Y	146

#define BOMB_BOMB_STAT_NORMAL_WIDTH	116
#define BOMB_BOMB_STAT_NORMAL_HEIGHT	65
#define BOMB_BOMB_STAT_SCARED_WIDTH	116
#define BOMB_BOMB_STAT_SCARED_HEIGHT	80
#define BOMB_BOMB_STAT_EXPLODED_WIDTH	116
#define BOMB_BOMB_STAT_EXPLODED_HEIGHT	100

VSDL_Image ULG_Bomb::sourceImage;
static bool imageReady = false;
static int bombY[3] = {BOMB_BOMB_STAT_NORMAL_IMAGE_Y, BOMB_BOMB_STAT_SCARED_IMAGE_Y, BOMB_BOMB_STAT_EXPLODED_IMAGE_Y};
static int bombMaxFrames[3] = {9, 7, 7};
static int bombWidth[3] = {BOMB_BOMB_STAT_NORMAL_WIDTH, BOMB_BOMB_STAT_SCARED_WIDTH, BOMB_BOMB_STAT_EXPLODED_WIDTH};
static int bombHeight[3] = {BOMB_BOMB_STAT_NORMAL_HEIGHT, BOMB_BOMB_STAT_SCARED_HEIGHT, BOMB_BOMB_STAT_EXPLODED_HEIGHT};

void ULG_Bomb::Init()
{
	int ret;

	if (imageReady == false){

		ret = sourceImage.LoadImage(BOMB_FILE, VSDL_RGB(BOMB_R, BOMB_G, BOMB_B));

		if (ret < 0){
			imageReady = false;
			return ;
		}

		imageReady = true;
	}

	status = BOMB_STAT_NORMAL;
	lastStatus = BOMB_STAT_NORMAL;
	//Setup animations
	animas[0].SetFrameInterval(DEFAULT_FRAME_INTERVAL);
	animas[0].SetMaxFrames(bombMaxFrames[0]);
	animas[1].SetFrameInterval(DEFAULT_FRAME_INTERVAL);
	animas[1].SetMaxFrames(bombMaxFrames[1]);
	animas[2].SetFrameInterval(DEFAULT_FRAME_INTERVAL);
	animas[2].SetMaxFrames(bombMaxFrames[2]);
}

ULG_Bomb::ULG_Bomb()
{

}

ULG_Bomb::ULG_Bomb(VSDL_Point point)
{
	startXY = point;
}

ULG_Bomb::ULG_Bomb(VSDL_Point point, ULG_BombStatus status)
{
	startXY = point;
	this->status = status;
}

void ULG_Bomb::SetStartXY(VSDL_Point point)
{
	startXY = point;
}

void ULG_Bomb::SetStatus(ULG_BombStatus status)
{
	this->status = status;	
}

void ULG_Bomb::SetAnimaInterval(int frameInterval)
{
	animas[0].SetFrameInterval(frameInterval);
	animas[1].SetFrameInterval(frameInterval);
	animas[2].SetFrameInterval(frameInterval);
}

int ULG_Bomb::GetWidth()
{
	return (BOMB_BOMB_STAT_NORMAL_WIDTH);
}

int ULG_Bomb::GetHeight()
{
	return (BOMB_BOMB_STAT_NORMAL_HEIGHT);
}

void ULG_Bomb::OnMouseMove(int mouseX, int mouseY)
{
	SDL_Rect hotArea;

	if (status >= BOMB_STAT_EXPLODED || status < BOMB_STAT_NORMAL){
		//Exploded or Dead, no need to check hot area
		return ;
	}

	hotArea.x = startXY.x;
	hotArea.y = startXY.y;
	hotArea.w = bombWidth[status] >> 1;
	hotArea.h = bombHeight[status];

	if (mouseX > hotArea.x && mouseX < hotArea.x + hotArea.w && mouseY > hotArea.y && mouseY < hotArea.y + hotArea.h){
		//Hot area entered, switch to BOMB_STAT_SCARED status
		status = BOMB_STAT_SCARED;
	}else{
		status = BOMB_STAT_NORMAL;
	}

	if (lastStatus != status){
		//Switch status now
		lastStatus = status;
		animas[status].SetFrame(0);
	}
}

bool ULG_Bomb::OnMouseDown(int mouseX, int mouseY)
{
	SDL_Rect hotArea;
	bool inRect = false;

	if (status >= BOMB_STAT_EXPLODED || status < 0){
		return false;
	}

	hotArea.x = startXY.x;
	hotArea.y = startXY.y;
	hotArea.w = bombWidth[status] >> 1;
	hotArea.h = bombHeight[status];

	if (mouseX > hotArea.x && mouseX < hotArea.x + hotArea.w && mouseY > hotArea.y && mouseY < hotArea.y + hotArea.h){
		//Hot area entered, switch to BOMB_STAT_EXPLODED status
		status  = BOMB_STAT_EXPLODED;
		inRect = true;
	}

	if (lastStatus != status){
		//Switch status now
		lastStatus = status;
		animas[status].SetFrame(0);
	}

	return inRect;
}

void ULG_Bomb::Show(SDL_Surface *destSurf)
{
	int currentFrame;
	VSDL_Clip imageClip;

	if (status == BOMB_STAT_DEAD || imageReady == false){
		return ;
	}

	//Show current frame
	currentFrame = animas[status].GetCurrentFrame();
	imageClip.SetClip(currentFrame * bombWidth[status], bombY[status], bombWidth[status], bombHeight[status]);
	sourceImage.BlitClip(destSurf, imageClip, startXY);
	//Debug
#ifdef ULG_BOMB_DEBUG
	VSDL_RGB rgb(100, 100, 100);
	SPG_Rect(destSurf, startXY.x, startXY.y, startXY.x + (bombWidth[status] >> 1), startXY.y + bombHeight[status], rgb.GetRGB32(destSurf));
#endif

	animas[status].OnAnimation();
	//Special case for status BOMB_STAT_EXPLODED
	if (status == BOMB_STAT_EXPLODED){
		//If next frame is 0, then go to BOMB_STAT_DEAD status
		if (animas[status].GetCurrentFrame() == 0){
			status = BOMB_STAT_DEAD;
			lastStatus = BOMB_STAT_DEAD;
		}
	}
}
